#define CATCH_CONFIG_MAIN  // 这行告诉Catch提供main()函数，只能在一个CPP文件中出现
#include <catch2/catch_test_macros.hpp>
#include "../src/HashMap.hpp"  // 包含你的HashMap头文件

TEST_CASE("HashMap基础功能测试", "[hashmap][basic]") {
    WinstJackonw::HashMap<int, std::string> map;
    
    SECTION("默认构造的HashMap为空") {
        REQUIRE(map.Find(1) == nullptr);
    }
    
    SECTION("插入和查找元素") {
        auto result = map.Insert({1, "one"});
        REQUIRE(result.second == true);  // 插入成功
        REQUIRE(result.first->first == 1);
        REQUIRE(result.first->second == "one");
        
        auto found = map.Find(1);
        REQUIRE(found != nullptr);
        REQUIRE(found->second == "one");
    }
}

TEST_CASE("HashMap边界情况测试", "[hashmap][edge]") {
    WinstJackonw::HashMap<int, int> map;
    
    SECTION("插入重复键返回false") {
        map.Insert({1, 100});
        auto result = map.Insert({1, 200});  // 重复键
        REQUIRE(result.second == false);  // 插入失败
        REQUIRE(map.Find(1)->second == 100);  // 原始值不变
    }
    
    SECTION("查找不存在的键返回nullptr") {
        REQUIRE(map.Find(999) == nullptr);
    }
}

TEST_CASE("HashMap操作测试", "[hashmap][operations]") {
    WinstJackonw::HashMap<int, std::string> map;
    
    // 准备测试数据
    map.Insert({1, "one"});
    map.Insert({2, "two"});
    map.Insert({3, "three"});
    
    SECTION("删除存在的元素") {
        auto result = map.Erase(2);
        REQUIRE(map.Find(2) == nullptr);
        REQUIRE(map.Find(1) != nullptr);  // 其他元素应存在
    }
    
    SECTION("删除不存在的元素") {
        auto result = map.Erase(999);  // 不存在的键
        REQUIRE(map.Find(1) != nullptr);  // 现有元素不受影响
    }
}

TEST_CASE("HashMap哈希冲突测试", "[hashmap][collision]") {
    // 使用简单哈希函数模拟冲突
    struct SimpleHash {
        std::size_t operator()(int in) const { return in % 3; }  // 只有3个桶
    };
    
    WinstJackonw::HashMap<int, std::string, SimpleHash> map;
    
    SECTION("相同桶的不同键都能正确存储") {
        map.Insert({1, "first"});   // 1 % 3 = 1
        map.Insert({4, "fourth"});  // 4 % 3 = 1 → 相同桶
        
        REQUIRE(map.Find(1) != nullptr);
        REQUIRE(map.Find(4) != nullptr);
        REQUIRE(map.Find(1)->second == "first");
        REQUIRE(map.Find(4)->second == "fourth");
    }
}
